package net.ib.mtalk.global;

import net.ib.mtalk.util.AesCipher;
import net.ib.mtalk.util.Base64;
import net.ib.mtalk.util.MTalkLogWriter;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.telephony.TelephonyManager;

/**
 * 액서스토큰을 쓰고 읽는 함수<br/>
 * net.ib.mtalk.global에서만 visible 함.
 * @author urunimi
 *
 */
public class MessageUtils {
	
	synchronized static boolean putMessageToPreferences(com.google.protobuf.micro.MessageMicro token) {
		boolean result = false;
		try {
			byte[] deviceIdBytes = getDeviceId().getBytes("UTF-8");
			byte[] keyBytes = new byte[16];
			System.arraycopy(deviceIdBytes, 0, keyBytes, 0, (deviceIdBytes.length >= 16)? 16 : deviceIdBytes.length);

			AesCipher cipher = new AesCipher(keyBytes, keyBytes);
			byte[] originalBytes = token.toByteArray();
			byte[] encrpytedBytes = cipher.encrypt(originalBytes);
			SharedPreferences.Editor prefs = GlobalPreferences.getSharedPreferences().edit();
			prefs.putString(token.getClass().getSimpleName(), Base64.encode(encrpytedBytes)).commit();
			result = true;
		} catch (Exception ioe) {
			MTalkLogWriter.e("Could not write file " + ioe.getMessage());
		}
		return result;
	}
	
	/**
	 * AccessToken
	 * @return
	 */
	synchronized static <T extends com.google.protobuf.micro.MessageMicro> T getMessageFromPreferences(Class<T> type) {
		try {
			byte[] deviceIdBytes = getDeviceId().getBytes("UTF-8");
			byte[] keyBytes = new byte[16];
			System.arraycopy(deviceIdBytes, 0, keyBytes, 0, (deviceIdBytes.length >= 16)? 16 : deviceIdBytes.length);
			
			AesCipher cipher = new AesCipher(keyBytes, keyBytes);
			String encrptedString = GlobalPreferences.getSharedPreferences().getString(type.getSimpleName(), null);
			if (encrptedString == null)
				return null;

			byte[] decrypedBytes = cipher.decrypt(Base64.decode(encrptedString));
			T data = type.newInstance();
			data.mergeFrom(decrypedBytes);
			return type.cast(data);
		} catch (Exception ioe) {
			MTalkLogWriter.e("Could not write file " + ioe.getMessage());
			return null;
		}
	}
	
	
	/**
	 * <H1>Private키를 발급하는 과정</H1><br/>
	 * Device에 dependent하도록 DeviceId를 키로 삼는다.<br/>
	 * 가끔 Null이 떨어지는 경우가 있으므로 이를 대비하여 전역 변수들에 의한 키도 준비
	 * @return 만들어진 키 문자열
	 */
	private static String getDeviceId() {
		
		TelephonyManager tManager = (TelephonyManager) GlobalApplication.getContext().getSystemService(Context.TELEPHONY_SERVICE);
		String uid = tManager.getDeviceId();
		
		if(uid == null) {
			uid = String.valueOf(
	    	Build.BOARD.length()%10+ Build.BRAND.length()%10 +
	    	Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
	    	Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
	    	Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
	    	Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
	    	Build.TAGS.length()%10 + Build.TYPE.length()%10 +
	    	Build.USER.length()%10);
		}
		return uid;
	}
}
